﻿using System;
using System.Linq;
using System.Windows;
using Microsoft.Practices.Unity;

namespace PrismNavigationFramework.MVVM
{
    public class ViewCreationService : IViewCreationService
    {
        private readonly IUnityContainer _unityContainer;

        public ViewCreationService(IUnityContainer unityContainer)
        {
            _unityContainer = unityContainer;
        }

        public object CreateView<TViewType>()
        {
            return this.CreateView(typeof (TViewType));
        }

        public object CreateView(Type viewInterfaceType)
        {
            var view = this._unityContainer.Resolve(viewInterfaceType);

            var viewModelType = typeof(ViewModel<>).MakeGenericType(viewInterfaceType);

            if (this._unityContainer.IsRegistered(viewModelType))
            {
                var viewModelAny = this._unityContainer.Resolve(viewModelType);

                var viewModelThatAcceptsView = viewModelAny as IAcceptView;
                if (viewModelThatAcceptsView != null)
                {
                    viewModelThatAcceptsView.SetView(view);
                }

                var viewAsFrameworkElement = view as FrameworkElement;
                if (viewAsFrameworkElement != null)
                {
                    viewAsFrameworkElement.DataContext = viewModelAny;
                }
            }

            return view;
        }


        public object CreateView(string viewName)
        {
            var viewInterfaceName = string.Format("I{0}View", viewName);
            var viewTypeName = string.Format("{0}View", viewName);

            var viewTypeRegistration =
                this._unityContainer.Registrations.Where(
                    p => (p.RegisteredType.IsInterface && p.RegisteredType.Name.ToLower() == viewInterfaceName.ToLower()
                        || !p.RegisteredType.IsInterface && p.RegisteredType.Name.ToLower() == viewTypeName.ToLower())).FirstOrDefault();

            if (viewTypeRegistration != null)
            {
                return this.CreateView(viewTypeRegistration.RegisteredType);
            }

            return null;
        }
    }
}